package com.efounder.message.socket;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

public class MessageSplitHandler extends ByteToMessageDecoder
{
	private static int messageTypeLenght = 1;
	private static int msgLength = 4;
	@Override
	protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
	{
		byte[]  decoded = decode(ctx, in);
		if(decoded != null)
		{
//			ByteBuf buffer = Unpooled.buffer();
//			buffer.writeBytes(decoded);
			out.add(decoded);
		}
	}

	/**
	 * Create a frame out of the {@link ByteBuf} and return it.
	 * 
	 * @param ctx
	 *            the {@link ChannelHandlerContext} which this
	 *            {@link ByteToMessageDecoder} belongs to
	 * @param in
	 *            the {@link ByteBuf} from which to read data
	 * @return frame the {@link ByteBuf} which represent the frame or
	 *         {@code null} if no frame could be created.
	 */
	protected byte[] decode(@SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, ByteBuf in) throws Exception
	{
		if(in.readableBytes() < messageTypeLenght)
		{
			return null;
		} else
		{
			byte messageType = in.readByte();
			byte[] b = null;
			switch((int)messageType)
			{
				case 0:
				{
					b =  new byte[]{0};
					break;
				}
				default:
				{
					b = this.getTypeX(ctx, in,messageType);
					break;
				}
			}
			if(b==null)
			{
				in.readerIndex(in.readerIndex()-messageTypeLenght);
				return null;
			}else
			{
				return b;
			}
		}
	}
	
	private byte[] getTypeX(@SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx,ByteBuf in,byte messageType)
	{
		if(in.readableBytes() < 4)
		{
			return null;
		} else
		{
			int msgLength = in.readInt();
			if(in.readableBytes() < msgLength)
			{
				in.readerIndex(in.readerIndex()-4);
				return null;
			}else
			{
				byte[] b = new byte[messageTypeLenght+4+msgLength];
//				b[0]=(byte) (messageType >> 8);
				b[0]=(byte) (messageType >> 0);
				b[1]=(byte) (msgLength >> 8*3);
				b[2]=(byte) (msgLength >> 8*2);
				b[3]=(byte) (msgLength >> 8);
				b[4]=(byte) (msgLength >> 0);
				in.readBytes(b,messageTypeLenght+4,msgLength);
				return b;
			}
		}
	}
}
